#lang r5rs

(define (stream-ref s n)
  (if (= n 0)
      (stream-car s)
      (stream-ref (stream-cdr s) (- n 1))))

(define (stream-map proc s)
  (if (null? s)
      '()
      (cons-stream (proc (stream-car s))
                   (stream-map proc (stream-cdr s)))))
(define (stream-for-each proc s)
  (if (null? s)
      '()
      (begin
        (proc (stream-car s))
        (stream-for-each proc (stream-cdr s)))))



(define (cons-stream x y)
  (cons x (delay y)))

(define (stream-car s)
  (car s))

(define (stream-cdr s)
  (force (cdr s)))

(define (force x)
  (x))
(define (delay x)
  (define having-asked #f)
  (define result #f)
  (lambda ()
    (if (having-asked)
        result
        (begin
          (set! result (x))
          (set! having-asked #t)
          result))))